package cn.wizzer.app.web.commons.ext.websocket.action.live;

import cn.wizzer.app.sys.modules.services.SysSensitiveService;
import cn.wizzer.app.user.modules.models.User;
import cn.wizzer.app.user.modules.models.constant.ChatConstant;
import cn.wizzer.app.user.modules.models.enums.EquipmentEnum;
import cn.wizzer.app.user.modules.services.ChatReportService;
import cn.wizzer.app.user.modules.services.UserService;
import cn.wizzer.app.web.commons.ext.websocket.main.action.BaseNettyAction;
import cn.wizzer.app.web.commons.ext.websocket.main.action.NettyAction;
import cn.wizzer.app.web.commons.ext.websocket.main.result.ChatResult;
import cn.wizzer.app.web.commons.utils.NettyMsgUtil;
import cn.wizzer.app.web.commons.utils.RedisUtil;
import cn.wizzer.app.web.commons.utils.TokenUtilImpl;
import cn.wizzer.framework.base.Result;
import cn.wizzer.framework.util.JSONUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import org.apache.commons.lang3.EnumUtils;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

import static cn.wizzer.app.user.modules.models.constant.ChatConstant.CHAT_ROOM;
import static cn.wizzer.app.user.modules.models.constant.ChatConstant.CHAT_USER;

/**
 * @author 22099
 */
@IocBean
@NettyAction(uri = "/login")
public class LoginAction extends BaseNettyAction {

    @Inject
    private RedisService redisService;

    @Inject
    UserService userService;

    @Inject
    TokenUtilImpl tokenUtil;

    @Reference
    @Inject
    SysSensitiveService sensitiveService;

    @Reference
    @Inject
    ChatReportService chatReportService;

    public static BaseNettyAction instance() {
        return BaseNettyAction.instance(LoginAction.class);
    }

    @Override
    public Result action(Channel income, JSONObject params) {
        JSONObject loginInfo = JSONUtil.toJSON(params);
        boolean flag = tokenUtil.verifyToken(loginInfo.getString("appid"), loginInfo.getString("token"), EnumUtils.getEnum(EquipmentEnum.class, loginInfo.getString("equipment")));
        if (flag) {
            //region 用户信息
            String roomId = RedisUtil.hget(User.class, ChatConstant.CHAT_USER, income.id().toString()).getRoomId();
            User user = userService.fetch(loginInfo.getString("appid"));
            NutMap res = new NutMap().
                    addv("id", user.getId())
                    .addv("nickName", user.getNickName())
                    .addv("headPicture", user.getHeadPicture())
                    .addv("roomManager", user.isRoomManager())
                    .addv("sessionDisabled", user.isSessionDisabled())
                    .addv("manageRoom", new HashSet<String>())
                    .addv("channelId", income.id().toString())
                    .addv("roomId", roomId);
            //endregion
            //region 清空原有用户数据
            ChannelGroup channels = NettyMsgUtil.getLiveRoomChannels(ChatConstant.DEFAULT, income);
            Collection<String> users = RedisUtil.hgetAll(CHAT_USER).values();
            List<String> oldChannel = users.stream()
                    .map((val) -> (User) JSONUtil.parseStringToJavaBean(User.class, val))
                    .filter(that -> null!=that&&user.getId().equals(that.getId()))
                    .map(u -> u.getChannelId())
                    .collect(Collectors.toList());
            channels.stream().filter(channel -> oldChannel.contains(channel.id().toString())).forEach(channel -> {
                NettyMsgUtil.send(channel, ChatResult.MessageTypeEnum.SYSTEM, ChatResult.ActionEnum.LOGIN_ERROR,null,"重复登录");
                channel.close();
            });
            oldChannel.forEach(channelId->{
                RedisUtil.hdel(CHAT_USER, channelId);
            });
            //endregion
            //region 缓存当前用户数据
            RedisUtil.hset(ChatConstant.CHAT_USER, income.id().toString(), res);
            RedisUtil.hset(CHAT_ROOM + roomId, income.id().toString(), user.getId());
            //endregion
            //登录成功
            return ChatResult.actionSend(res, ChatResult.MessageTypeEnum.ACTION, ChatResult.ActionEnum.LOGIN_SUCCESS, "登录成功");
        } else {
            return ChatResult.sysSend(ChatResult.MessageTypeEnum.SYSTEM, ChatResult.ActionEnum.REMAND, "信息有误");
        }

    }

    @Override
    public Result subscribe(String subscribeParam) {
        return Result.success();
    }


}
